﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System;
using System.Configuration;
using System.Diagnostics;
using System.IO.IsolatedStorage;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using YahooSports.Api;
using YahooSports.Api.Exceptions;
using YahooSports.Api.Sports.Models;
using YahooSports.OAuthLib.Core;
using System.Data.Entity;

namespace Fire_DataImporter
{
    public partial class Form_Importer : Form
    {

        private static readonly string CONSUMER_KEY = ConfigurationManager.AppSettings["ConsumerKey"];
        private static readonly string CONSUMER_SECRET = ConfigurationManager.AppSettings["ConsumerSecret"];
        private static readonly string YAHOO_KEY_NFL_CURRENT_YEAR = ConfigurationManager.AppSettings["Yahoo_Key_NFL_CurrentYear"];
        private const string TOKEN_FILE = "token";

        private static readonly IsolatedStorageFile Storage = IsolatedStorageFile.GetUserStoreForAssembly();


        private static AccessToken Token;
        private static SportsProvider Client;
        private string errObj = string.Empty;


        public Form_Importer()
        {
            InitializeComponent();
        }

        private void btnImportData_Click(object sender, EventArgs e)
        {
            ProcessYahooImport();
        }

        /// <summary>
        /// Starts the Yahoo Import Process
        /// </summary>
        private void ProcessYahooImport()
        {

            //Do we have a token file?
            if (Storage.FileExists(TOKEN_FILE))
            {
                try
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    using (Stream stream = Storage.OpenFile(TOKEN_FILE, FileMode.Open))
                    {
                        Token = formatter.Deserialize(stream) as AccessToken;
                    }
                }
                catch
                {
                    MessageBox.Show("ERROR: Error deserializing the token!");
                }
            } //end token file check


            //No We Don't
            if (Token != null)
            {

                //initiate the SportsProvider
                Client = new SportsProvider("", CONSUMER_KEY, CONSUMER_SECRET, Token);

                //Perform quick tests first
                League oLeagueTest = QuickLeagueTest();

                Team oTeamTest = QuickTeamTest();

                Player oPlayerTest = QuickPlayerTest();

                Game oGameTest = QuickNFLTest();


                //Finally, let's Start the Process the Import
                Game oGame = ProcessPlayerImport();

            }
            else
            {

                string consumerKey = CONSUMER_KEY;
                string consumerSecret = CONSUMER_SECRET;
                string appUrl = string.Empty;
                string authCallback = "oob";

                Func<string, string> userAuthCallback = url =>
                {
                    using (Process p = new Process())
                    {
                        p.StartInfo = new ProcessStartInfo("chrome.exe", url);
                       // p.StartInfo = new ProcessStartInfo("iexplore.exe", url);
                        p.Start();
                        return Microsoft.VisualBasic.Interaction.InputBox("Enter key from (" + url + "):");
                    }
                };

                SportsProvider client = new SportsProvider(appUrl, CONSUMER_KEY, CONSUMER_SECRET);
                client.AuthenticateAsync(userAuthCallback, completeOperation =>
                {
                    completeOperation(); // this must be called.
                    Token = client.Token;
                   this.label1.Text = "\nAsynchronous Authentication Operation completed successfully!\n";
                });
               this.label1.Text = "Waiting up to 60 seconds...";
                int count = 0;
                while (!client.IsAuthenticated && count < 60)
                {
                    Console.Write(". ");
                    Thread.Sleep(1000);
                    count++;
                }

                if (!client.IsAuthenticated)
                    return; // exit.

                using (Stream stream = Storage.OpenFile(TOKEN_FILE, FileMode.Create))
                {
                    //DataContractSerializer serializer = new DataContractSerializer(typeof(AccessToken));    
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(stream, Token);
                    //serializer.WriteObject(stream, Token);
                }
            }

           this.label1.Text = String.Format("Token: {0}\nSecret: {1}\n", Token.Token, Token.TokenSecret);
           this.label1.Text = "Press any key to continue...";
            Console.Read();
        }

        private Game QuickNFLTest()
        {

            try
            {
                FantasyContent content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/game/nfl/");//http://fantasysports.yahooapis.com/fantasy/v2/player/223.p.5479");//http://fantasysports.yahooapis.com/fantasy/v2/game/223/leagues;league_keys=223.l.431");//http://fantasysports.yahooapis.com/fantasy/v2/game/nba");
                return content.Game;
            }
            catch (SportsApiException ex)
            {
               this.label1.Text = "OAuth exception caught: " + ex.Message;
               this.label1.Text = "Refreshing token...";
                Client.RefreshToken();
               this.label1.Text = "Refresh token successful!";
               this.label1.Text = "Trying to execute normal authenticated request again!";
                FantasyContent content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/game/nfl/");//"http://fantasysports.yahooapis.com/fantasy/v2/player/223.p.5479");//http://fantasysports.yahooapis.com/fantasy/v2/game/223/leagues;league_keys=223.l.431");//http://fantasysports.yahooapis.com/fantasy/v2/game/nba");
                return content.Game;
            }

        }

        public  League QuickLeagueTest()
        {
            try
            {
                FantasyContent content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/league/238.l.178574/scoreboard;week=2");//http://fantasysports.yahooapis.com/fantasy/v2/player/223.p.5479");//http://fantasysports.yahooapis.com/fantasy/v2/game/223/leagues;league_keys=223.l.431");//http://fantasysports.yahooapis.com/fantasy/v2/game/nba");
                return content.League;
            }
            catch (SportsApiException ex)
            {
               this.label1.Text = "OAuth exception caught: " + ex.Message;
               this.label1.Text = "Refreshing token...";
                Client.RefreshToken();//Token = oauthProvider.RefreshToken(Token);
               this.label1.Text = "Refresh token successful!";
               this.label1.Text = "Trying to execute normal authenticated request again!";
                FantasyContent content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/league/238.l.178574/scoreboard;week=2");//"http://fantasysports.yahooapis.com/fantasy/v2/player/223.p.5479");//http://fantasysports.yahooapis.com/fantasy/v2/game/223/leagues;league_keys=223.l.431");//http://fantasysports.yahooapis.com/fantasy/v2/game/nba");
                return content.League;
            }
        }


        public  Team QuickTeamTest()
        {
            try
            {
                FantasyContent content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/team/223.l.431.t.9/roster/players");//http://fantasysports.yahooapis.com/fantasy/v2/player/223.p.5479");//http://fantasysports.yahooapis.com/fantasy/v2/game/223/leagues;league_keys=223.l.431");//http://fantasysports.yahooapis.com/fantasy/v2/game/nba");
                return content.Team;
            }
            catch (SportsApiException ex)
            {
               this.label1.Text = "OAuth exception caught: " + ex.Message;
               this.label1.Text = "Refreshing token...";
                Client.RefreshToken();
               this.label1.Text = "Refresh token successful!";
               this.label1.Text = "Trying to execute normal authenticated request again!";
                FantasyContent content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/team/223.l.431.t.9/roster/players");//"http://fantasysports.yahooapis.com/fantasy/v2/player/223.p.5479");//http://fantasysports.yahooapis.com/fantasy/v2/game/223/leagues;league_keys=223.l.431");//http://fantasysports.yahooapis.com/fantasy/v2/game/nba");
                return content.Team;
            }
        }

        public  Player QuickPlayerTest()
        {
            try
            {
                FantasyContent content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/player/238.p.6619/stats");//http://fantasysports.yahooapis.com/fantasy/v2/player/223.p.5479");//http://fantasysports.yahooapis.com/fantasy/v2/game/223/leagues;league_keys=223.l.431");//http://fantasysports.yahooapis.com/fantasy/v2/game/nba");
                return content.Player;
            }
            catch (SportsApiException ex)
            {
               label1.Text = "OAuth exception caught: " + ex.Message;
               this.label1.Text = "Refreshing token...";
                Client.RefreshToken();
               this.label1.Text = "Refresh token successful!";
               this.label1.Text = "Trying to execute normal authenticated request again!";
                FantasyContent content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/player/238.p.6619/stats");//"http://fantasysports.yahooapis.com/fantasy/v2/player/223.p.5479");//http://fantasysports.yahooapis.com/fantasy/v2/game/223/leagues;league_keys=223.l.431");//http://fantasysports.yahooapis.com/fantasy/v2/game/nba");
                return content.Player;
            }
        }
        /// <summary>
        /// Process the Player Import
        /// </summary>
        /// <returns></returns>
        private Game ProcessPlayerImport()
        {

            FantasyContent content = null;
            try
            {
                //base string for players
                Int16 currentCounter = 0;
                Int32 playerFound = 1;
                string basePlayerURL = "http://fantasysports.yahooapis.com/fantasy/v2/game/" + YAHOO_KEY_NFL_CURRENT_YEAR + "/players";
                string paramPlayerURL = ";start=" + currentCounter + "/stats";

                //FantasyContent content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/game/273/players;start=51/stats");//http://fantasysports.yahooapis.com/fantasy/v2/player/223.p.5479");//http://fantasysports.yahooapis.com/fantasy/v2/game/223/leagues;league_keys=223.l.431");//http://fantasysports.yahooapis.com/fantasy/v2/game/nba");

                Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseAlways<DBAccessContext>());
                using (var db = new DBAccessContext())
                {

                    //did we get any players?
                    do
                    {
                        label1.Text = "Importing 25 Players beginning from " + currentCounter.ToString();
                        //get the new request from Yahoo
                        content = Client.ExecuteRequest<FantasyContent>(@basePlayerURL + ";start=" + currentCounter + "/stats");

                        //handle our increments
                        playerFound = content.Game.Players.Count();
                        currentCounter += 25;                           //prepare to get the next 25

                        foreach (Player pl in content.Game.Players)
                        {
                            if (pl.TransactionInfo == null)
                            {
                                pl.TransactionInfo = new TransactionData();
                            }
                            //build up our list
                            db.Players.Add(pl);
                        }

                        //save to the database
                        db.SaveChanges();

                    } while (playerFound > 0);
                }

                label1.Text = "Import Done";

                return content.Game;
            }
            catch (SportsApiException ex)
            {
               this.label1.Text = "OAuth exception caught: " + ex.Message;
               this.label1.Text = "Refreshing token...";
                Client.RefreshToken();
               this.label1.Text = "Refresh token successful!";
               this.label1.Text = "Trying to execute normal authenticated request again!";
                content = Client.ExecuteRequest<FantasyContent>(@"http://fantasysports.yahooapis.com/fantasy/v2/game/273/players;start=1/stats");
                return content.Game;
            }
        }

    }
}